/**
 * 
 */
package de.wesemann.mediahandbook.le.activity;

import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.text.Editable;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import de.wesemann.jdedun.entities.district.districts.DistrictDistrict;
import de.wesemann.jdedun.entities.mediahandbook.branches.MediahandbookBranche;
import de.wesemann.jdedun.entities.mediahandbook.companies.MediahandbookCompaniesContainer;
import de.wesemann.jdedun.entities.mediahandbook.companies.MediahandbookCompany;
import de.wesemann.jdedun.exceptions.PageNotFoundException;
import de.wesemann.mediahandbook.le.R;
import de.wesemann.mediahandbook.le.activity.helper.AbstractAsyncTask;
import de.wesemann.mediahandbook.le.activity.helper.AbstractListActivity;
import de.wesemann.mediahandbook.le.activity.helper.ActivityHelper;
import de.wesemann.mediahandbook.le.adapter.CompanyAdapter;
import de.wesemann.mediahandbook.le.listener.CompaniesOverviewEndlessScrollListener;
import de.wesemann.mediahandbook.le.util.CompanyUtil;
import de.wesemann.mediahandbook.le.util.DistrictUtil;
import de.wesemann.mediahandbook.le.widget.TitleWidget;

/**
 * @author Lars W.
 * 
 */
public class CompaniesOverview extends AbstractListActivity {
	private CompanyAdapter mComAdap;
	private MediahandbookCompaniesContainer mCompaniesContainer = null;
	private static final String LOG_TAG = CompaniesOverview.class.getSimpleName();
	private ListView mList;
	private TitleWidget mTitleWidget;

	private SearchCompaniesByBranchesTask mCompaniesByBranchesTask;
	private LoadAllCompaniesTask mLoadAllCompaniesTask;
	private SearchCompaniesTask mSearchCompaniesTask;
	private SearchCompaniesByDistrictsTask mSearchCompaniesByDistrictsTask;

	private String mSearchValue;
	private MediahandbookBranche mBranch;
	private DistrictDistrict mDistrict;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.companies_overview);
		Log.d(LOG_TAG, "onCreate()");
		final Bundle extras = getIntent().getExtras();

		mList = (ListView) findViewById(android.R.id.list);
		mTitleWidget = (TitleWidget) findViewById(R.id.co_titleWidget);
		Object retained = getLastNonConfigurationInstance();
		loadRightTask(retained, extras);

	}

	private void loadRightTask(Object retained, Bundle extras) {
		if (retained instanceof SearchCompaniesByBranchesTask) {
			// SearchComapniesByBranchesTask - on configuration change
			Log.d(LOG_TAG, "Reclaiming previous background task SearchCompaniesByBranchesTask.");
			// setUpTitleWidget(getString(R.string.companies) +
			// getString(R.string.in_branch) + mTitleSuffix);
			setUpTitleWidget(getString(R.string.companies));
			mCompaniesByBranchesTask = (SearchCompaniesByBranchesTask) retained;
			mCompaniesByBranchesTask.setActivity(this);
		} else if (retained instanceof LoadAllCompaniesTask) {
			// LoadItemTask - on configuration change
			Log.d(LOG_TAG, "Reclaiming previous background task LoadItemsTask.");
			setUpTitleWidget(getString(R.string.companies));
			mLoadAllCompaniesTask = (LoadAllCompaniesTask) retained;
			mLoadAllCompaniesTask.setActivity(this);
		} else if (retained instanceof SearchCompaniesTask) {
			// SearchItemsTask - on configuration change
			Log.d(LOG_TAG, "Reclaiming previous background task SearchCompaniesTask.");
			// setUpTitleWidget(getString(R.string.companies) + " found by " +
			// mTitleSuffix);
			setUpTitleWidget(getString(R.string.companies));
			mSearchCompaniesTask = (SearchCompaniesTask) retained;
			mSearchCompaniesTask.setActivity(this);
		} else if (retained instanceof SearchCompaniesByDistrictsTask) {
			// SearchCompaniesByDistrictsTask - on configuration change
			Log.d(LOG_TAG, "Reclaiming previous background task SearchCompaniesByDistrictsTask.");
			// setUpTitleWidget(getString(R.string.companies) +
			// getString(R.string.in_district) + mTitleSuffix);
			setUpTitleWidget(getString(R.string.companies));
			mSearchCompaniesByDistrictsTask = (SearchCompaniesByDistrictsTask) retained;
			mSearchCompaniesByDistrictsTask.setActivity(this);
		} else if (extras != null) {
			// Comming from another acitivity
			if (extras.containsKey(BranchOverview.BRANCH_TAG)) {
				// SearchCompaniesByBranchesTask
				Log.d(LOG_TAG, "Create list: all companies by branch");
				mBranch = (MediahandbookBranche) extras.get(BranchOverview.BRANCH_TAG);
				// setUpTitleWidget(getString(R.string.companies) +
				// " in branch " + mBranch.getName());
				setUpTitleWidget(getString(R.string.companies));
				mCompaniesByBranchesTask = new SearchCompaniesByBranchesTask(this);
				mCompaniesByBranchesTask.execute(mBranch);
			} else if (extras.containsKey(DistrictOverview.DISTRICT_TAG)) {
				// SearchCmopaniesByDistrictsTask
				Log.d(LOG_TAG, "Create list: all companies by district");
				mDistrict = (DistrictDistrict) extras.get(DistrictOverview.DISTRICT_TAG);
				// setUpTitleWidget(getString(R.string.companies) +
				// " in district " + mDistrict.getName());
				setUpTitleWidget(getString(R.string.companies));
				Log.d(LOG_TAG, mTitleWidget.getTitle());
				mSearchCompaniesByDistrictsTask = new SearchCompaniesByDistrictsTask(this);
				mSearchCompaniesByDistrictsTask.execute(mDistrict);
			}

		} else {
			setUpTitleWidget(getString(R.string.companies));
			Log.d(LOG_TAG, "Creating new background task LoadAllCompaniesTask");
			mLoadAllCompaniesTask = new LoadAllCompaniesTask(this);
			mLoadAllCompaniesTask.execute();
		}
	}

	private void setUpTitleWidget(String titleName) {

		mTitleWidget.setTitle(titleName);
		mTitleWidget.setLeftIcon(R.drawable.bu_house_conf);

		mTitleWidget.hideProgressBar();
	}

	private void createList() {
		mComAdap = new CompanyAdapter(this, mCompaniesContainer.getData());
		if (null != mCompaniesContainer.getPaging()) {
			mList.setOnScrollListener(new CompaniesOverviewEndlessScrollListener(3, mComAdap, mList,
					mCompaniesContainer, mTitleWidget.getProgressBar()));
		}
		setListAdapter(mComAdap);
	}

	/**
	 * 
	 * @author Lars W.
	 * 
	 */
	private class LoadAllCompaniesTask extends AbstractAsyncTask<Void, Void, MediahandbookCompaniesContainer> {

		private LoadAllCompaniesTask(CompaniesOverview activity) {
			super(activity);
		}

		@Override
		protected MediahandbookCompaniesContainer doInBackground(Void... params) {

			try {
				return CompanyUtil.getFirstCompanies(30);
			} catch (FileNotFoundException e) {
				Log.e(LOG_TAG, e.getMessage());
				cancel(true);
			}
			return null;
		}

		@Override
		protected void onPreExecute() {
			Log.d(LOG_TAG, "PRE Executing LoadItemsTask");
			activity.showDialog(LOADING_DIALOG);

		}

	}

	private class SearchCompaniesByDistrictsTask extends
			AbstractAsyncTask<DistrictDistrict, Void, MediahandbookCompaniesContainer> {

		protected SearchCompaniesByDistrictsTask(ActivityHelper activity) {
			super(activity);
		}

		@Override
		protected MediahandbookCompaniesContainer doInBackground(DistrictDistrict... params) {
			String postcode = null;
			try {
				postcode = DistrictUtil.getPostcodeFromDistrict(params[0].getId());
			} catch (PageNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			if (postcode != null) {
				MediahandbookCompaniesContainer compsCont = new MediahandbookCompaniesContainer();
				try {
					compsCont.setData(CompanyUtil.searchCompanyBySomething("postcode", postcode));
					return compsCont;
				} catch (FileNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			return null;
		}

		@Override
		protected void onPreExecute() {
			Log.d(LOG_TAG, "PRE Executing SearchCompaniesByBranchesTask");
			activity.showDialog(LOADING_DIALOG);
		}

	}

	/**
	 * 
	 * @author Lars W.
	 * 
	 */
	private class SearchCompaniesByBranchesTask extends
			AbstractAsyncTask<MediahandbookBranche, Integer, MediahandbookCompaniesContainer> {
		private int myProgress;
		private List<MediahandbookCompany> foundCompanies = new ArrayList<MediahandbookCompany>();
		private MediahandbookCompaniesContainer companiesInTheContainer = new MediahandbookCompaniesContainer();

		private SearchCompaniesByBranchesTask(CompaniesOverview activity) {
			super(activity);
		}

		@Override
		protected MediahandbookCompaniesContainer doInBackground(MediahandbookBranche... params) {
			Log.d(LOG_TAG, "start loading everything " + params[0].getName() + " " + params[0].getId());
			myProgress = 5;
			publishProgress(myProgress);
			for (Integer companyId : params[0].getCompanies()) {

				myProgress++;
				publishProgress(myProgress);
				if (companyId != null) {
					try {
						foundCompanies.addAll(CompanyUtil.searchCompanyById(companyId));
					} catch (FileNotFoundException e) {
						Log.e(LOG_TAG, e.getMessage());
						this.cancel(true);
					}

				}
				myProgress++;
				publishProgress(myProgress);
			}
			Log.d(LOG_TAG, foundCompanies.size() + " companies found");
			myProgress = 100;
			publishProgress(myProgress);
			companiesInTheContainer.setData(foundCompanies);
			return companiesInTheContainer;
		}

		@Override
		protected void onPreExecute() {
			Log.d(LOG_TAG, "PRE Executing SearchCompaniesByBranchesTask");
			activity.showDialog(LOADING_DIALOG);
			activity.setProgressBarVisibility(true);
			myProgress = 0;
		}

		@Override
		protected void onProgressUpdate(Integer... values) {
			activity.setProgress(values[0]);
		}

	}

	/**
	 * 
	 * @author Lars W.
	 * 
	 */
	private class SearchCompaniesTask extends AbstractAsyncTask<String, Void, MediahandbookCompaniesContainer> {

		private SearchCompaniesTask(CompaniesOverview activity) {
			super(activity);
			// TODO Auto-generated constructor stub
		}

		@Override
		protected MediahandbookCompaniesContainer doInBackground(String... params) {
			try {
				return CompanyUtil.searchCompaniesByNameWithLimit(30, params[0]);
			} catch (FileNotFoundException e) {
				Log.e(LOG_TAG, e.getMessage());
				this.cancel(true);
			}
			return null;
		}

		@Override
		protected void onPreExecute() {
			Log.d(LOG_TAG, "PRE Executing LoadItemsTask");
			activity.showDialog(LOADING_DIALOG);

		}

	}

	/**
	 * When the aSyncTask has notified the activity that it has completed, we
	 * can refresh the list control, and attempt to dismiss the dialog. We'll
	 * only dismiss the dialog
	 */
	@Override
	public void onTaskCompleted(AbstractAsyncTask<?, ?, ?> task) {
		Log.i(LOG_TAG, "Activity has been notified the task is complete.");
		try {
			Log.d(LOG_TAG, "try to get the container");
			if (task instanceof SearchCompaniesByBranchesTask)
				this.mCompaniesContainer = mCompaniesByBranchesTask.get();
			else if (task instanceof LoadAllCompaniesTask) {
				this.mCompaniesContainer = mLoadAllCompaniesTask.get();
			} else if (task instanceof SearchCompaniesTask) {
				Log.d(LOG_TAG, "SearchItemsTask is not null. Try to get the data");
				this.mCompaniesContainer = mSearchCompaniesTask.get();
			} else if (task instanceof SearchCompaniesByDistrictsTask) {
				this.mCompaniesContainer = mSearchCompaniesByDistrictsTask.get();
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}
		Log.d(LOG_TAG, mCompaniesContainer.getData().size() + " companies in the container");
		if (mCompaniesContainer != null && mCompaniesContainer.getData().size() > 0) {
			createList();
		} else {
			Toast.makeText(CompaniesOverview.this, getString(R.string.search_no_results), Toast.LENGTH_LONG).show();
		}
		// Check added because dismissDialog throws an exception if the current
		// activity hasn't shown it. This Happens if task finishes early enough
		// before an orientation change that the dialog is already gone when
		// the previous activity bundles up the dialogs to reshow.
		if (mShownDialog) {
			dismissDialog(LOADING_DIALOG);
			Toast.makeText(this, getString(R.string.finished), Toast.LENGTH_LONG).show();
		}
	}

	@Override
	public void reload(AbstractAsyncTask<?, ?, ?> task) {
		dismissDialog(LOADING_DIALOG);
		Log.d(LOG_TAG, "Reloading Task");
		if (task.getreLoadTries() < 3) {
			if (task instanceof SearchCompaniesTask) {
				mSearchCompaniesTask.execute(mSearchValue);
			} else if (task instanceof LoadAllCompaniesTask) {
				mLoadAllCompaniesTask.execute();
			} else if (task instanceof SearchCompaniesByBranchesTask) {
				mCompaniesByBranchesTask.execute(mBranch);
			} else if (task instanceof SearchCompaniesByDistrictsTask) {
				mSearchCompaniesByDistrictsTask.execute(mDistrict);
			} else {
				Toast.makeText(this, getString(R.string.error_while_loading), Toast.LENGTH_SHORT).show();
			}
		} else {
			Toast.makeText(this, getString(R.string.error_while_loading), Toast.LENGTH_SHORT).show();
		}
	}

	/**
	 * After a screen orientation change, this method is invoked. As we're going
	 * to state save the task, we can no longer associate it with the Activity
	 * that is going to be destroyed here.
	 */
	@Override
	public Object onRetainNonConfigurationInstance() {
		if (mSearchCompaniesTask != null) {
			Log.d(LOG_TAG, "Save the SearchItemsTask");
			mSearchCompaniesTask.setActivity(null);
			mCompaniesByBranchesTask = null;
			mLoadAllCompaniesTask = null;
			mSearchCompaniesByDistrictsTask = null;
			return mSearchCompaniesTask;
		} else if (mCompaniesByBranchesTask != null) {
			Log.d(LOG_TAG, "Save the CompaniesByBranchesTask");
			mCompaniesByBranchesTask.setActivity(null);
			mLoadAllCompaniesTask = null;
			mSearchCompaniesTask = null;
			mSearchCompaniesByDistrictsTask = null;
			return mCompaniesByBranchesTask;
		} else if (mLoadAllCompaniesTask != null) {
			Log.d(LOG_TAG, "Save the LoadItemsTask");
			mLoadAllCompaniesTask.setActivity(null);
			mCompaniesByBranchesTask = null;
			mSearchCompaniesTask = null;
			mSearchCompaniesByDistrictsTask = null;
			return mLoadAllCompaniesTask;
		} else if (mSearchCompaniesByDistrictsTask != null) {
			Log.d(LOG_TAG, "Save the SearchCompaniesByDistrictsTask");
			mSearchCompaniesByDistrictsTask.setActivity(null);
			mCompaniesByBranchesTask = null;
			mSearchCompaniesTask = null;
			mLoadAllCompaniesTask = null;
			return mSearchCompaniesByDistrictsTask;
		}
		return null;

	}

	/**
	 * 
	 * @param view
	 */
	public void onSearchClick(View view) {
		if (view.getId() == R.id.title_search) {
			// Toast.makeText(this, "search clicked",
			// Toast.LENGTH_SHORT).show();
			AlertDialog.Builder builder = new AlertDialog.Builder(this);
			builder.setTitle(getString(R.string.search_title));
			final EditText edit = new EditText(this);
			builder.setView(edit);

			builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog, int whichButton) {
					Editable value = edit.getText();
					if (value.toString().length() != 0) {
						mSearchValue = value.toString().trim();
						mSearchValue = mSearchValue.replace(" ", "%20");
						Log.d(LOG_TAG, "I'm looking for " + mSearchValue);
						mLoadAllCompaniesTask = null;
						mCompaniesByBranchesTask = null;
						mSearchCompaniesTask = new SearchCompaniesTask(CompaniesOverview.this);
						mSearchCompaniesTask.execute(mSearchValue);
					}
				}
			});

			builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog, int whichButton) {
					// Canceled.
				}
			});

			builder.show();

		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.ListActivity#onListItemClick(android.widget.ListView,
	 * android.view.View, int, long)
	 */
	@Override
	protected void onListItemClick(ListView l, View v, int position, long id) {
		super.onListItemClick(l, v, position, id);
		MediahandbookCompany company = (MediahandbookCompany) getListView().getItemAtPosition(position);
		Intent intent = new Intent(this, CompanyDetail.class);
		intent.putExtra("MediahandbookCompany", company);
		startActivity(intent);
	}

	@Override
	protected void onDestroy() {
		Log.d(LOG_TAG, "onDestroy()");

		super.onDestroy();
	}

	@Override
	protected void onPause() {
		super.onPause();
		Log.d(LOG_TAG, "onPause()");
//		Log.d(LOG_TAG, "setPreference for title " + mTitleWidget.getTitle());
		// Editor editor = getPreferences(MODE_PRIVATE).edit();
		// editor.putString("titleName", mTitleWidget.getTitle());
		// editor.commit();

	}

	@Override
	protected void onRestart() {
		super.onRestart();
		Log.d(LOG_TAG, "onRestart()");
	}

	@Override
	protected void onResume() {
		Log.d(LOG_TAG, "onResume()");
		super.onResume();
		// SharedPreferences preferences = getPreferences(MODE_PRIVATE);
		// Log.d(LOG_TAG, "getPreference for title " +
		// preferences.getString("titleName", ""));
		// if (!preferences.getString("titleName", "").equals("")
		// && !preferences.getString("titleName",
		// "").equals(getString(R.string.companies))) {
		// setUpTitleWidget(preferences.getString("titleName", ""));
		// }
		// mTitleWidget.setTitle(preferences.getString("titleName", ""));

	}

	@Override
	protected void onStop() {
		Log.d(LOG_TAG, "onStop()");
		// Editor editor = getPreferences(MODE_PRIVATE).edit();
		// editor.putString("titleName", "");
		// editor.commit();
		super.onStop();
	}

	@Override
	public void finish() {
		Log.d(LOG_TAG, "finish()");

		super.finish();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.ListActivity#onRestoreInstanceState(android.os.Bundle)
	 */
	@Override
	protected void onRestoreInstanceState(Bundle state) {
		Log.d(LOG_TAG, "onRestoreInstanceState");
		// mTitleSuffix = state.getString("titleSuffix");
		// mSearchValue = state.getString("searchValue");
		super.onRestoreInstanceState(state);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onSaveInstanceState(android.os.Bundle)
	 */
	@Override
	protected void onSaveInstanceState(Bundle outState) {
		Log.d(LOG_TAG, "onSaveInstanceState");
		// outState.putString("titleSuffix", mTitleSuffix);
		// outState.putString("searchValue", mSearchValue);
		super.onSaveInstanceState(outState);
	}

}
